#include "Singleton.hpp"
#include <pthread.h>
#include <unistd.h>

TicketGrab *TicketGrab::m_instance = nullptr;

void Test1()
{
  Singletion *ptr1 = Singletion::GetInstance();
  Singletion *ptr2 = Singletion::GetInstance();
  fprintf(stdout, "ptr1: %p, ptr2: %p\n", ptr1, ptr2);
}

// 测试拷贝构造函数和重载赋值问题
void Test2()
{
  Singletion *ptr3 = Singletion::GetInstance();
  // Singletion obj1 = *ptr3;
  // Singletion obj2 = obj1;
  // 拷贝构造会默认生成
  // fprintf(stdout, "obj1: %p, obj2: %p\n", &obj1, &obj2);
}

TicketGrab *ptr1 = TicketGrab::GetInstance();
void *Handler(void *arg)
{
  pthread_detach(pthread_self());
  // pthread_t fds = *(pthread_t*)arg;
  long fds = (long)arg;
  // 存在重入现象，线程不安全
  while (true)
  {
    if (ptr1->TicketNum() > 0)
    {
      ptr1->Grabbing(fds);
      // usleep(1);
    }
    else
      break;
  }
}

// 测试线程问题
void Test3()
{
  pthread_t tds[5];
  for (long i = 0; i < 5; i++)
  {
    // 注意：多线程传址和传值的区别(会出现重入问题)
    pthread_create(tds + i, nullptr, Handler, (void *)i);
    // sleep(1);
  }
  // 注意：如果主线程提前退出的话，其他线程的会继续运行但是结果就不会打印到主线程显示器上了
  sleep(3);

  // usleep(1000);
  // for(int i = 0; i < 5; i++)
  // {
  //   pthread_join(tds[i], nullptr);
  // }
}

int main()
{
  // Test1();
  // Test2();
  Test3();
  return 0;
}
